package org.example.infrastructure.adapter.repository;


import org.example.domain.order.model.entity.OrderEntity;
import org.example.domain.transaction.adapter.repository.ITransactionRepository;
import org.example.domain.transaction.model.entity.PayCallbackEntity;
import org.example.domain.transaction.model.entity.RefundCallBackEntity;
import org.example.domain.transaction.model.valobj.PayStatusEnumVO;
import org.example.infrastructure.dao.IOrderDao;
import org.example.infrastructure.dao.IOrderTransactionDao;
import org.example.infrastructure.dao.IRefundCallBackTopicRetryDao;
import org.example.infrastructure.dao.ISucceedPayCallBackTopicRetryDao;
import org.example.infrastructure.dao.po.OrderPO;
import org.example.infrastructure.dao.po.OrderTransactionPO;
import org.example.infrastructure.dao.po.RefundCallBackTopicRetryPO;
import org.example.infrastructure.dao.po.SucceedPayCallBackTopicRetryPO;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yinghuashen
 * @version 1.0
 * @description
 * @date 2025/3/10 19:16
 */

@Repository
public class TransactionRepository implements ITransactionRepository {

    @Resource
    private IOrderDao orderDao;

    @Resource
    private IOrderTransactionDao orderTransactionDao;

    @Resource
    private ISucceedPayCallBackTopicRetryDao succeedPayCallBackTopicRetryDao;

    @Resource
    private IRefundCallBackTopicRetryDao refundCallBackTopicRetryDao;

    @Override
    public boolean checkPayCallbackResultExisted(String outTradeNo) {
        OrderTransactionPO orderTransactionPO = orderTransactionDao.getByOutTradeNo(outTradeNo);
        // 检查是否外部订单号是否重复
        return orderTransactionPO != null;
    }

    @Override
    public boolean checkInOrderExisted(String orderId) {
        OrderPO orderPO = orderDao.getOrderById(orderId);
        // 检查内部订单是否存在
        return orderPO != null;
    }

    @Override
    public boolean checkInOrderIsPendingPayment(String orderId) {
        OrderPO orderPO = orderDao.getOrderById(orderId);
        Integer status = orderPO.getStatus();
        return status == OrderEntity.OrderStatus.PENDING_PAYMENT.getCode();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void savePayCallbackResult(PayCallbackEntity payCallbackEntity) {
        OrderTransactionPO orderTransactionPO = new OrderTransactionPO();

        orderTransactionPO.setOrderId(payCallbackEntity.getOrderId());
        orderTransactionPO.setOutTradeNo(payCallbackEntity.getOutTradeNo());
        if(payCallbackEntity.getStatus() == 1){
            orderTransactionPO.setCreateTime(payCallbackEntity.getPayTime());
        }
        orderTransactionPO.setSource(payCallbackEntity.getSource());
        orderTransactionPO.setPayPrice(payCallbackEntity.getPayPrice());
        orderTransactionPO.setStatus(payCallbackEntity.getStatus());

        orderTransactionDao.saveOrderTransaction(orderTransactionPO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveSucceedPayCallbackMsg(PayCallbackEntity payCallbackEntity) {
        SucceedPayCallBackTopicRetryPO succeedPayCallBackTopicRetryPO = new SucceedPayCallBackTopicRetryPO();
        succeedPayCallBackTopicRetryPO.setOrderId(payCallbackEntity.getOrderId());
        succeedPayCallBackTopicRetryPO.setOutTradeNo(payCallbackEntity.getOutTradeNo());
        succeedPayCallBackTopicRetryPO.setPayTime(payCallbackEntity.getPayTime());

        succeedPayCallBackTopicRetryDao.saveSucceedPayCallBackTopicRetry(succeedPayCallBackTopicRetryPO);
    }

    @Override
    public boolean checkPaid(String outTradeNo) {
        OrderTransactionPO po = orderTransactionDao.getByOutTradeNo(outTradeNo);
        if(po == null){
            return false;
        }
        return po.getStatus() == PayStatusEnumVO.SUCCESS.getCode();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean executeRefund(String outTradeNo) {
        Map<String, Object> params = new HashMap<>();
        params.put("outTradeNo", outTradeNo);
        params.put("status", PayStatusEnumVO.REFUND.getCode());
        int i = orderTransactionDao.updateStatusByOutTradeNo(params);
        return i == 1;
    }

    @Override
    public boolean checkRefunded(String outTradeNo) {
        OrderTransactionPO po = orderTransactionDao.getByOutTradeNo(outTradeNo);
        if(po == null){
            return false;
        }
        return po.getStatus() == PayStatusEnumVO.REFUND.getCode();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveRefundCallbackMsg(RefundCallBackEntity refundCallBackEntity) {
        RefundCallBackTopicRetryPO refundCallBackTopicRetryPO = new RefundCallBackTopicRetryPO();
        refundCallBackTopicRetryPO.setOrderId(refundCallBackEntity.getOrderId());
        refundCallBackTopicRetryPO.setOutTradeNo(refundCallBackEntity.getOutTradeNo());
        refundCallBackTopicRetryPO.setRefundPrice(refundCallBackEntity.getRefundPrice());
        refundCallBackTopicRetryPO.setSource(refundCallBackEntity.getSource());
        refundCallBackTopicRetryDao.saveRefundCallBackTopicRetry(refundCallBackTopicRetryPO);
    }
}
